package org.dromara.app.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.dromara.app.domain.AppUser;
import org.dromara.app.domain.bo.AppUserBo;
import org.dromara.app.domain.vo.AppUserVo;
import org.dromara.app.mapper.AppUserMapper;
import org.dromara.app.service.AppUserService;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * App端用户信息Service业务层处理
 *
 * @author ruoyi
 */
@Service
@RequiredArgsConstructor
public class AppUserServiceImpl extends ServiceImpl<AppUserMapper, AppUser> implements AppUserService {


    /**
     * 查询App端用户信息
     */
    @Override
    public AppUserVo queryById(Long userId) {
        return baseMapper.selectVoById(userId);
    }

    /**
     * 查询App端用户信息列表
     */
    @Override
    public TableDataInfo<AppUserVo> queryPageList(AppUserBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<AppUser> lqw = buildQueryWrapper(bo);
        Page<AppUserVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询App端用户信息列表
     */
    @Override
    public List<AppUserVo> queryList(AppUserBo bo) {
        LambdaQueryWrapper<AppUser> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<AppUser> buildQueryWrapper(AppUserBo bo) {
        LambdaQueryWrapper<AppUser> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getUserName()), AppUser::getUserName, bo.getUserName());
        lqw.like(StringUtils.isNotBlank(bo.getNickName()), AppUser::getNickName, bo.getNickName());
        lqw.eq(StringUtils.isNotBlank(bo.getPhone()), AppUser::getPhone, bo.getPhone());
        lqw.eq(StringUtils.isNotBlank(bo.getEmail()), AppUser::getEmail, bo.getEmail());
        lqw.eq(StringUtils.isNotBlank(bo.getSex()), AppUser::getSex, bo.getSex());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), AppUser::getStatus, bo.getStatus());
        return lqw;
    }

    /**
     * 新增App端用户信息
     */
    @Override
    public Boolean insertByBo(AppUserBo bo) {
        AppUser add = BeanUtil.toBean(bo, AppUser.class);
        validEntityBeforeSave(add);
        // 加密密码
        if (StringUtils.isNotBlank(add.getPassword())) {
            add.setPassword(BCrypt.hashpw(add.getPassword()));
        }
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setUserId(add.getUserId());
        }
        return flag;
    }

    /**
     * 修改App端用户信息
     */
    @Override
    public Boolean updateByBo(AppUserBo bo) {
        AppUser update = BeanUtil.toBean(bo, AppUser.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(AppUser entity) {
        // TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除App端用户信息
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            // TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 根据用户账号查询用户信息
     */
    @Override
    public AppUserVo selectUserByUserName(String userName) {
        return baseMapper.selectUserByUserName(userName);
    }

    /**
     * 根据手机号查询用户信息
     */
    @Override
    public AppUserVo selectUserByPhone(String phone) {
        return baseMapper.selectUserByPhone(phone);
    }

    /**
     * 根据邮箱查询用户信息
     */
    @Override
    public AppUserVo selectUserByEmail(String email) {
        return baseMapper.selectUserByEmail(email);
    }

    /**
     * 校验用户账号是否唯一
     */
    @Override
    public boolean checkUserNameUnique(String userName) {
        return baseMapper.checkUserNameUnique(userName) == 0;
    }

    /**
     * 校验手机号码是否唯一
     */
    @Override
    public boolean checkPhoneUnique(String phone) {
        return baseMapper.checkPhoneUnique(phone) == 0;
    }

    /**
     * 校验email是否唯一
     */
    @Override
    public boolean checkEmailUnique(String email) {
        return baseMapper.checkEmailUnique(email) == 0;
    }

    /**
     * 用户注册
     */
    @Override
    public Boolean register(AppUserBo bo) {
        // 校验账号唯一性
        if (!checkUserNameUnique(bo.getUserName())) {
            throw new RuntimeException("用户账号已存在");
        }
        // 校验手机号唯一性
        if (StringUtils.isNotBlank(bo.getPhone()) && !checkPhoneUnique(bo.getPhone())) {
            throw new RuntimeException("手机号已存在");
        }
        // 校验邮箱唯一性
        if (StringUtils.isNotBlank(bo.getEmail()) && !checkEmailUnique(bo.getEmail())) {
            throw new RuntimeException("邮箱已存在");
        }
        return insertByBo(bo);
    }

    /**
     * 修改用户密码
     */
    @Override
    public Boolean updatePassword(Long userId, String oldPassword, String newPassword) {
        AppUser user = baseMapper.selectById(userId);
        if (ObjectUtil.isNull(user)) {
            throw new RuntimeException("用户不存在");
        }
        if (!BCrypt.checkpw(oldPassword, user.getPassword())) {
            throw new RuntimeException("旧密码错误");
        }
        user.setPassword(BCrypt.hashpw(newPassword));
        return baseMapper.updateById(user) > 0;
    }

    /**
     * 重置用户密码
     */
    @Override
    public Boolean resetPassword(Long userId, String newPassword) {
        AppUser user = new AppUser();
        user.setUserId(userId);
        user.setPassword(BCrypt.hashpw(newPassword));
        return baseMapper.updateById(user) > 0;
    }

    /**
     * 更新用户状态
     */
    @Override
    public Boolean updateUserStatus(Long userId, String status) {
        return baseMapper.update(null,
                new LambdaUpdateWrapper<AppUser>()
                        .set(AppUser::getStatus, status)
                        .eq(AppUser::getUserId, userId)) > 0;
    }

}